package org.lep.leetcode.palindrome.palindromepartitioning;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Source : https://oj.leetcode.com/problems/palindrome-partitioning/
 *
 * Created by lverpeng on 2017/8/27.
 *
 * Given a string s, partition s such that every substring of the partition is a palindrome.
 *
 * Return all possible palindrome partitioning of s.
 *
 * For example, given s = "aab",
 *
 * Return
 *
 *   [
 *     ["aa","b"],
 *     ["a","a","b"]
 *   ]
 *
 */
public class PalindromePartitioning {


    /**
     * 将字符串进行任意位置的分割，找到分割后的子串都是回文字符串的结果
     *
     * 因为需要判断字符串的各个子串是不是回文字符串，所以可以使用longest palindrome substring中的动态规划
     *
     * 将每一次分割后的子串的判断结果记录下来
     *
     * 然后私用DFS寻找所有子串是回文的情形
     *
     * @param str
     * @return
     */
    public List<List<String>> partition (String str) {
        boolean[][] table = new boolean[str.length()][str.length()];
        for (int i = str.length()-1; i >= 0; i--) {
            for (int j = i; j < str.length(); j++) {
                if ((i+1 >= j-1 || table[i+1][j-1]) && str.charAt(i) == str.charAt(j) ) {
                    table[i][j] = true;
                }
            }
        }
        List<List<String>> result = new ArrayList<List<String>>();
        List<String> patition = new ArrayList<String>();
        findPartitions(str, 0, table, result, patition);
        return result;
    }
    private void findPartitions (String str, int start, boolean[][] table, List<List<String>> result, List<String> partition) {
        if (str.length() == start) {
            result.add(new ArrayList<String>(partition));
            return ;
        }
        for (int i = start; i < str.length(); i++) {
            if (table[start][i]) {
                partition.add(str.substring(start, i+1));
                findPartitions(str, i + 1, table, result, partition);
                partition.remove(partition.size()-1);
            }
        }
    }

    private static void print (List<List<String>> list) {
        for (List<String> strList : list) {
            System.out.println(Arrays.toString(strList.toArray(new String[strList.size()])));
        }
        System.out.println();
    }

    public static void main(String[] args) {
        PalindromePartitioning palindromePartitioning = new PalindromePartitioning();

        print(palindromePartitioning.partition("aab"));
    }
}
